package com.aaa.json.dao;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: dem0jdbc
 * @description:
 * @author: 诸葛龙辰
 * @create: 2023-02-24 09:14
 * @version:通用（基础）的JDBC封装工具类
 **/
public class BaseDao {
//定义常量 常量不能被改变的
    private static String UrL = "jdbc:mysql://localhost:3306/db_qy164_test?useSSL=false";
    private static String USER = "root";
    private static String PASSWORD = "123456";

    static {
        //加载驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取Connection
     * @return
     */
    public static Connection getConnection() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(UrL, USER, PASSWORD);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return connection;
    }

    /**
     *
     * @param preparedStatement
     * @param paramsArray
     *  设置参数
     */
    public static void setParams(PreparedStatement preparedStatement, Object[] paramsArray) throws SQLException {
        // 判断参数数组是否为null
        if (paramsArray == null || paramsArray.length == 0) {
            System.out.println("参数数组为空错误");
            return;
        }
          // 循环遍历
        for (int i = 0; i < paramsArray.length; i++) {
            //因为preparedstatement设置参数下标从1开始，循环数组从下标0开始
            preparedStatement.setObject(i+1,paramsArray[i]);

        }
    }

    /**
     *
     * @param sql   要执行更新的语句
     * @param params  需要的参数
     * @return  更新方法
     */

    public static  int executeUpdate(String sql,Object[] params){
        //获取connection
        Connection connection = getConnection();
        //定义返回值
        int resultNum =0;
        PreparedStatement preparedStatement = null;

        //获取preparedStatement 语句执行对象，并传入sql语句
        try {
           preparedStatement = connection.prepareStatement(sql);
            //调用封装方法获取参数
            setParams(preparedStatement,params);
            //执行更新，并返回执行成功条数
            ////return preparedStatement . executeUpdate();
            resultNum = preparedStatement.executeUpdate();

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        finally {
            //关闭资源
            closeAll(connection,preparedStatement,null);
        }
        //return 0
        return  resultNum;
    }
    /**执行的语句  查询
     * 需要的参数  。。。jdk5的新特性相当于数组 但是数组输入必须参数,没有参数必须传null使用... 没有参数可以不传
     */
    public  static List<Map> executQuery(String sql,Object...params){
        //调用封装类获取Connection
        Connection connection = getConnection();
        PreparedStatement preparedStatement = null;
        //定义返回结果集
        List<Map> returnMapList = new ArrayList<>();
        try {
            //获取语句执行对象 ，并传入sql
         preparedStatement = connection.prepareStatement(sql);
            //调用封装方法设置参数
            setParams(preparedStatement,params);
            //执行查询并返回结果集
            ResultSet resultSet = preparedStatement.executeQuery();
            //通过resultset获取元数据对象
            ResultSetMetaData metaData =resultSet.getMetaData();
            //动态获取执行语句的列数量
            int columnCount = metaData.getColumnCount();
            //定义Map 集合
            Map map = null;
            //循环结果集
            while (resultSet.next()){
                //每循环一次都要实例化一个Map  把当前行的内容放入里面
                map = new HashMap();
                // dept_ .no dept_ .name Loc
                // 11 可能就   郑州
                //...
/**
 *map.put(列名称,resultSet.getObject(1));
 */
                for (int i = 1; i <= columnCount; i++) {
                    //根据下标获取列名称
                    String columnName = metaData.getColumnName(i);
                    //根据下标获取列的数据
             Object columnValue =  resultSet.getObject(i);
                    //把列名称和值存入map里
                    map.put(columnName,columnValue);
                }
                //把每行map放入返回集合
                returnMapList.add(map);

            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        finally {
            closeAll(connection,preparedStatement,null);
        }
        return  returnMapList;
    }

    /**
     * 关闭方法，后打开先关闭
     * @param connection
     * @param statement
     * @param resultSet
     */
     public  static  void  closeAll(Connection connection,Statement statement,ResultSet resultSet){
         try {
             if (resultSet!=null){
                 resultSet.close();
             }
         } catch (SQLException e) {
             throw new RuntimeException(e);
         }
         try {
             if (statement!=null){
                 statement.close();
             }
         } catch (SQLException e) {
             throw new RuntimeException(e);
         }
         try {
             if (connection!=null){
                 connection.close();
             }
         } catch (SQLException e) {
             throw new RuntimeException(e);
         }
     }
}

